package com.davidlife.javase.javaio;

import java.io.*;

/*
字节流的一个小练习：复制文件。
执行后会把编译生成的 .class 文件复制到项目工程的根目录下。
或若已打成可执行的jar包，则会复制到执行这个jar包时所在的路径。
    比如：D:\tt>java -jar D:\tmp\ByteStreamDemoCopyFiles.jar
    这是在tt目录下执行的 java -jar 命令，则就会复制到 tt 目录下，而非 tmp 目录下。

注意：当Java文件中包含非ASCII字符时，javac编译时最好指明所用的编码，因为不指明的话会默认用本地系统的编码。
     javac -encoding UTF-8 ByteStreamDemoCopyFiles.java    (若不指明编码，则默认的就相当于是：javac -encoding GBK ...)
 */
public class ByteStreamDemoCopyFiles {
    public static void main(String[] args) throws IOException {
        /*
        像下面这样写在IDE中可以正常执行，但若打成可执行jar包再运行就会报错。因为 getResource("ByteStreamDemoCopyFiles.class")
            返回的路径为 file:\D:\tmp\ByteStreamDemoCopyFiles.jar!\ByteStreamDemoCopyFiles.class， 而 File 类不可能通过这种
            路径来定位到jar包内的文件。

            为了解决能获得jar包内的资源文件的问题，可以使用 getResourceAsStream 方法直接得到资源的 InputStream。
        */
        //FileInputStream fis = new FileInputStream(ByteStreamDemoCopyFiles.class.getResource("ByteStreamDemoCopyFiles.class").getFile());

        //使用getResourceAsStream，可保证即使打成了jar包，这个复制程序也可正常运行。
            // （当然也可使用一些第三方的jar包，如Spring等就提供了这样的功能）
        InputStream is = ByteStreamDemoCopyFiles.class.getResourceAsStream("ByteStreamDemoCopyFiles.class");
        FileOutputStream fos = new FileOutputStream("ByteStreamDemoCopyFiles-Copy.class");

        byte[] bytes = new byte[1024];
        int len = 0;
        while ((len = is.read(bytes)) != -1) {
            System.out.println("Read length: " + len);
            fos.write(bytes, 0, len);
            //注意这里使用指定长度的write方法。因为若最后一次读取的小于1024字节，
            //则只会覆盖byte数组的前面部分，数组后面部分的字节仍为上次读取的内容，所以要指明只写入前len长度的字节。
        }

        fos.flush();
        fos.close();
        is.close();
    }

}
